package bean;

import java.util.List;
import java.util.Properties;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.log4j.Logger;

import bean.remote.MQSenderRemote;
import dominio.Configuracion;
import dominio.MQ;

@Stateless(name = "mqSenderBean")
@Remote(value = MQSenderRemote.class)
public class MQSenderBean implements MQSenderRemote {

	private final static Logger logger = Logger.getLogger(MQSenderBean.class);
	
	private Context getContext(Configuracion configuracion, MQ mq)
			throws NamingException {
		Context context = null;
		try {
			Properties jndiProps = new Properties();

			jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,
					"org.jboss.naming.remote.client.InitialContextFactory");

			// URL PROVIDER "remote://localhost:4447"
			String provideURL = "remote://" + configuracion.getTerminal() + ":4447";
			jndiProps.put(Context.PROVIDER_URL,
					System.getProperty(Context.PROVIDER_URL, provideURL));
			// username "test"
			jndiProps.put(Context.SECURITY_PRINCIPAL,
					System.getProperty("username", mq.getUsuario()));
			// password "Password1234!"
			jndiProps.put(Context.SECURITY_CREDENTIALS,
					System.getProperty("password", mq.getContrasenia()));
			// This is an important property to set if you want to do EJB
			// invocations via the remote-naming project
			// jndiProps.put("jboss.naming.client.ejb.context", true);
			// create a context passing these properties
			context = new InitialContext(jndiProps);

		} catch (NamingException e) {
			logger.error("No se conecta al contexto " + configuracion.toString(), e);
			context = new InitialContext();
		}

		return context;
	}

	/**
	 * 
	 * @param configuracionsSender
	 *            la cola de mensajeria a la cual se va a depositar el objeto a
	 *            compartir
	 * @param xml
	 *            la informacion que se desea compartir.
	 */
	@Override
	public void send(Configuracion configuracion, String xml) {
		logger.info("Se envia el siguiente mensaje " + xml);
		MessageProducer producer = null;
		Session session = null;
		Connection connection = null;
		try {
			final MQ mq = configuracion.getMq();
			Context context = getContext(configuracion, mq);
			ConnectionFactory connectionFactory = (ConnectionFactory) context
					.lookup(mq.getConnectionFactory());

			// Creo la JMS connection, session, producer, and consumer
			connection = connectionFactory.createConnection(mq.getUsuario(),
					mq.getContrasenia());

			// creo la session para poder crear el productor con un destino
			session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

			Destination destination = (Destination) context.lookup(mq
					.getDestination());

			// creo el productor
			producer = session.createProducer(destination);

			// inicio la conneccion
			connection.start();
			TextMessage textMessage = session.createTextMessage(xml);
			producer.send(textMessage);
			connection.stop();
			logger.info("Se envio el mensaje a modulo " + configuracion.toString());
		} catch (NamingException e) {
			logger.error("No manda el mensaje a la cola " + configuracion.toString(), e);
		} catch (JMSException e) {
			logger.error("No manda el mensaje a la cola " + configuracion.toString(), e);
		} finally {
			try {
				if (producer != null) {
					producer.close();
				}
				if (session != null) {
					session.close();
				}
				if (connection != null) {
					connection.close();
				}
			} catch (JMSException e) {
				logger.error("No manda el mensaje a la cola " + configuracion.toString(), e);
			}
		}
	}

	@Override
	public void send(List<Configuracion> configuracions, String xml) {
		for (Configuracion configuracion : configuracions) {
			send(configuracion, xml);
		}
	}

	@Override
	public void sendLogistica(Configuracion configuracion, String mensaje) {
		send(configuracion, mensaje);
	}
}